package com.example.launibleplugin

import android.content.Context
import android.util.Log
import com.example.launibleplugin.constants.BluetoothConstants
import com.example.launibleplugin.listener.BluetoothEventListener
import com.example.launibleplugin.listener.SimpleBluetoothEventListener
import com.example.launibleplugin.manager.BluetoothManager
import com.example.launibleplugin.model.BluetoothDevice
import com.example.launibleplugin.model.ConnectionInfo
import com.example.launibleplugin.model.DataRecord
import com.google.gson.Gson
import com.google.gson.JsonObject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

/**
 * 呼吸家蓝牙插件主类
 * Function: 提供统一的蓝牙设备操作API接口
 * Parameter: context - Android上下文
 * Note: 插件的主要入口类，封装所有蓝牙操作功能
 */
class LaUniBlePlugin private constructor(private val context: Context) {
    
    companion object {
        private const val TAG = BluetoothConstants.LOG_TAG_PLUGIN
        private const val VERSION = "1.0.0"
        
        @Volatile
        private var INSTANCE: LaUniBlePlugin? = null
        
        /**
         * Function: 获取插件单例实例
         * Parameter: context - Android上下文
         * Return: LaUniBlePlugin - 插件实例
         * Note: 使用单例模式确保全局唯一实例
         */
        fun getInstance(context: Context): LaUniBlePlugin {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: LaUniBlePlugin(context.applicationContext).also { INSTANCE = it }
            }
        }
    }
    
    // 核心组件
    private val bluetoothManager = BluetoothManager(context)
    private val gson = Gson()
    private val coroutineScope = CoroutineScope(Dispatchers.Main + Job())
    
    // 状态管理
    private var isInitialized = false
    private var pluginEventListener: BluetoothEventListener? = null
    
    // UniApp回调函数映射
    private val callbackMap = mutableMapOf<String, (String) -> Unit>()
    
    /**
     * Function: 初始化插件
     * Parameter: config - 初始化配置（JSON字符串）
     * Return: String - 初始化结果（JSON格式）
     * Note: 插件初始化，设置事件监听器
     */
    fun initialize(config: String = "{}"): String {
        return try {
            if (isInitialized) {
                return createResponse(true, "插件已初始化", mapOf("version" to VERSION))
            }
            
            Log.d(TAG, "初始化呼吸家蓝牙插件 v$VERSION")
            
            // 解析配置
            val configJson = gson.fromJson(config, JsonObject::class.java) ?: JsonObject()
            
            // 设置内部事件监听器
            bluetoothManager.setEventListener(createInternalEventListener())
            
            isInitialized = true
            
            createResponse(
                success = true,
                message = "插件初始化成功",
                data = mapOf(
                    "version" to VERSION,
                    "bluetoothAvailable" to bluetoothManager.isBluetoothAvailable(),
                    "hasPermissions" to bluetoothManager.hasRequiredPermissions()
                )
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "插件初始化失败", e)
            createResponse(false, "初始化失败: ${e.message}")
        }
    }
    
    /**
     * Function: 检查蓝牙状态
     * Return: String - 蓝牙状态信息（JSON格式）
     * Note: 检查蓝牙可用性和权限状态
     */
    fun checkBluetoothStatus(): String {
        return try {
            val status = mapOf(
                "bluetoothAvailable" to bluetoothManager.isBluetoothAvailable(),
                "hasPermissions" to bluetoothManager.hasRequiredPermissions(),
                "connectedDevices" to bluetoothManager.getConnectedDevices().size
            )
            
            createResponse(true, "状态检查完成", status)
            
        } catch (e: Exception) {
            Log.e(TAG, "检查蓝牙状态失败", e)
            createResponse(false, "状态检查失败: ${e.message}")
        }
    }
    
    /**
     * Function: 开始扫描设备
     * Parameter: options - 扫描选项（JSON字符串）
     * Return: String - 扫描启动结果（JSON格式）
     * Note: 开始扫描呼吸家蓝牙设备
     */
    fun startScan(options: String = "{}"): String {
        return try {
            if (!isInitialized) {
                return createResponse(false, "插件未初始化")
            }
            
            val optionsJson = gson.fromJson(options, JsonObject::class.java) ?: JsonObject()
            val timeout = optionsJson.get("timeout")?.asLong ?: BluetoothConstants.SCAN_TIMEOUT_MS
            val deviceNameFilter = optionsJson.get("deviceName")?.asString
            
            bluetoothManager.startScan(timeout, deviceNameFilter)
            
            createResponse(
                success = true,
                message = "开始扫描设备",
                data = mapOf(
                    "timeout" to timeout,
                    "filter" to (deviceNameFilter ?: "")
                )
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "启动扫描失败", e)
            createResponse(false, "启动扫描失败: ${e.message}")
        }
    }
    
    /**
     * Function: 停止扫描设备
     * Return: String - 停止扫描结果（JSON格式）
     * Note: 停止设备扫描
     */
    fun stopScan(): String {
        return try {
            bluetoothManager.stopScan()
            createResponse(true, "停止扫描")
            
        } catch (e: Exception) {
            Log.e(TAG, "停止扫描失败", e)
            createResponse(false, "停止扫描失败: ${e.message}")
        }
    }
    
    /**
     * Function: 连接设备
     * Parameter: deviceInfo - 设备信息（JSON字符串）
     * Return: String - 连接结果（JSON格式）
     * Note: 连接指定的蓝牙设备
     */
    fun connectDevice(deviceInfo: String): String {
        return try {
            if (!isInitialized) {
                return createResponse(false, "插件未初始化")
            }
            
            val deviceJson = gson.fromJson(deviceInfo, JsonObject::class.java)
            val deviceId = deviceJson.get("deviceId")?.asString
            val macAddress = deviceJson.get("macAddress")?.asString
            val deviceName = deviceJson.get("deviceName")?.asString
            val autoReconnect = deviceJson.get("autoReconnect")?.asBoolean ?: true
            
            if (deviceId.isNullOrBlank() || macAddress.isNullOrBlank()) {
                return createResponse(false, "设备信息不完整")
            }
            
            val device = BluetoothDevice(
                deviceId = deviceId,
                deviceName = deviceName,
                macAddress = macAddress
            )
            
            bluetoothManager.connectDevice(device, autoReconnect)
            
            createResponse(
                success = true,
                message = "开始连接设备",
                data = mapOf(
                    "deviceId" to deviceId,
                    "macAddress" to macAddress,
                    "autoReconnect" to autoReconnect
                )
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "连接设备失败", e)
            createResponse(false, "连接设备失败: ${e.message}")
        }
    }
    
    /**
     * Function: 发送测量指令
     * Parameter: deviceId - 设备ID
     * Parameter: commandCode - 命令码（1-开始测量，2-取消测量）
     * Return: String - 指令发送结果（JSON格式）
     * Note: 向呼吸家设备发送测量控制指令（需要握手完成）
     */
    fun sendMeasurementCommand(deviceId: String, commandCode: Int): String {
        return try {
            if (!isInitialized) {
                return createResponse(false, "插件未初始化")
            }
            
            Log.i(TAG, "发送测量指令请求: deviceId=$deviceId, commandCode=$commandCode")
            
            val success = bluetoothManager.sendMeasurementCommand(deviceId, commandCode)
            
            val data = mapOf(
                "deviceId" to deviceId,
                "commandCode" to commandCode,
                "commandName" to when (commandCode) {
                    1 -> "开始测量"
                    2 -> "取消测量"
                    else -> "未知指令"
                },
                "success" to success,
                "timestamp" to System.currentTimeMillis()
            )
            
            if (success) {
                // 触发测量指令响应事件
                val eventData = mapOf(
                    "success" to true,
                    "message" to "指令发送成功",
                    "deviceId" to deviceId,
                    "commandCode" to commandCode
                )
                notifyEvent("onMeasurementResponse", eventData)
                
                createResponse(true, "测量指令发送成功", data)
            } else {
                // 触发测量指令响应事件
                val eventData = mapOf(
                    "success" to false,
                    "message" to "指令发送失败",
                    "deviceId" to deviceId,
                    "commandCode" to commandCode
                )
                notifyEvent("onMeasurementResponse", eventData)
                
                createResponse(false, "测量指令发送失败", data)
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "发送测量指令异常", e)
            createResponse(false, "发送测量指令异常: ${e.message}")
        }
    }
    
    /**
     * Function: 直接发送测量指令
     * Parameter: deviceId - 设备ID
     * Parameter: commandCode - 命令码（1-开始测量，2-取消测量）
     * Return: String - 指令发送结果（JSON格式）
     * Note: 直接向呼吸家设备发送测量控制指令，绕过握手检查
     */
    fun sendDirectMeasurementCommand(deviceId: String, commandCode: Int): String {
        return try {
            if (!isInitialized) {
                return createResponse(false, "插件未初始化")
            }
            
            Log.i(TAG, "直接发送测量指令请求: deviceId=$deviceId, commandCode=$commandCode")
            
            val success = bluetoothManager.sendDirectMeasurementCommand(deviceId, commandCode)
            
            val data = mapOf(
                "deviceId" to deviceId,
                "commandCode" to commandCode,
                "commandName" to when (commandCode) {
                    1 -> "开始测量"
                    2 -> "取消测量"
                    else -> "未知指令"
                },
                "success" to success,
                "timestamp" to System.currentTimeMillis(),
                "direct" to true
            )
            
            if (success) {
                // 触发测量指令响应事件
                val eventData = mapOf(
                    "success" to true,
                    "message" to "直接指令发送成功",
                    "deviceId" to deviceId,
                    "commandCode" to commandCode,
                    "direct" to true
                )
                notifyEvent("onMeasurementResponse", eventData)
                
                createResponse(true, "直接测量指令发送成功", data)
            } else {
                // 触发测量指令响应事件
                val eventData = mapOf(
                    "success" to false,
                    "message" to "直接指令发送失败",
                    "deviceId" to deviceId,
                    "commandCode" to commandCode,
                    "direct" to true
                )
                notifyEvent("onMeasurementResponse", eventData)
                
                createResponse(false, "直接测量指令发送失败", data)
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "直接发送测量指令异常", e)
            createResponse(false, "直接发送测量指令异常: ${e.message}")
        }
    }
    
    /**
     * Function: 断开设备连接
     * Parameter: deviceId - 设备ID
     * Return: String - 断开连接结果（JSON格式）
     * Note: 断开指定设备的连接
     */
    fun disconnectDevice(deviceId: String): String {
        return try {
            if (deviceId.isBlank()) {
                return createResponse(false, "设备ID不能为空")
            }
            
            bluetoothManager.disconnectDevice(deviceId)
            
            createResponse(
                success = true,
                message = "断开设备连接",
                data = mapOf("deviceId" to deviceId)
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "断开连接失败", e)
            createResponse(false, "断开连接失败: ${e.message}")
        }
    }
    
    /**
     * Function: 发送数据到设备
     * Parameter: deviceId - 目标设备ID
     * Parameter: data - 要发送的数据（十六进制字符串）
     * Return: String - 发送结果（JSON格式）
     * Note: 向指定设备发送数据
     */
    fun sendData(deviceId: String, data: String): String {
        return try {
            if (deviceId.isBlank()) {
                return createResponse(false, "设备ID不能为空")
            }
            
            if (data.isBlank()) {
                return createResponse(false, "数据不能为空")
            }
            
            // 将十六进制字符串转换为字节数组
            val dataBytes = hexStringToByteArray(data)
            val success = bluetoothManager.sendData(deviceId, dataBytes)
            
            createResponse(
                success = success,
                message = if (success) "数据发送成功" else "数据发送失败",
                data = mapOf(
                    "deviceId" to deviceId,
                    "dataLength" to dataBytes.size
                )
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "发送数据失败", e)
            createResponse(false, "发送数据失败: ${e.message}")
        }
    }
    
    /**
     * Function: 获取已连接设备列表
     * Return: String - 设备列表（JSON格式）
     * Note: 获取当前已连接的设备信息
     */
    fun getConnectedDevices(): String {
        return try {
            val connectedDeviceIds = bluetoothManager.getConnectedDevices()
            val deviceInfoList = connectedDeviceIds.mapNotNull { deviceId ->
                val connectionInfo = bluetoothManager.getConnectionInfo(deviceId)
                if (connectionInfo != null) {
                    mapOf(
                        "deviceId" to deviceId,
                        "connectionId" to connectionInfo.connectionId,
                        "state" to connectionInfo.getStateDescription(),
                        "connectTime" to connectionInfo.connectTime,
                        "signalStrength" to connectionInfo.signalStrength
                    )
                } else null
            }
            
            createResponse(
                success = true,
                message = "获取设备列表成功",
                data = mapOf(
                    "devices" to deviceInfoList,
                    "count" to deviceInfoList.size
                )
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "获取设备列表失败", e)
            createResponse(false, "获取设备列表失败: ${e.message}")
        }
    }
    
    /**
     * Function: 测试所有可写特征
     * Parameter: deviceId - 目标设备ID
     * Parameter: testData - 测试数据（可选，默认为"TEST"）
     * Return: String - 测试结果（JSON格式）
     * Note: 调试功能，向所有可写特征发送测试数据，用于识别正确的通信特征
     */
    fun testAllWritableCharacteristics(deviceId: String, testData: String = "TEST"): String {
        return try {
            if (deviceId.isBlank()) {
                return createResponse(false, "设备ID不能为空")
            }
            
            if (!isInitialized) {
                return createResponse(false, "插件未初始化")
            }
            
            Log.d(TAG, "开始测试所有可写特征: $deviceId, 测试数据: $testData")
            
            val successfulCharacteristics = bluetoothManager.testAllWritableCharacteristics(deviceId, testData)
            
            createResponse(
                success = true,
                message = "测试完成",
                data = mapOf(
                    "deviceId" to deviceId,
                    "testData" to testData,
                    "successfulCharacteristics" to successfulCharacteristics,
                    "successCount" to successfulCharacteristics.size,
                    "timestamp" to System.currentTimeMillis()
                )
            )
            
        } catch (e: Exception) {
            Log.e(TAG, "测试可写特征失败: $deviceId", e)
            createResponse(false, "测试失败: ${e.message}")
        }
    }
    
    /**
     * Function: 设置事件回调
     * Parameter: eventType - 事件类型
     * Parameter: callback - 回调函数
     * Note: 为UniApp设置事件回调函数
     */
    fun setEventCallback(eventType: String, callback: (String) -> Unit) {
        callbackMap[eventType] = callback
        Log.d(TAG, "设置事件回调: $eventType")
    }
    
    /**
     * Function: 移除事件回调
     * Parameter: eventType - 事件类型
     * Note: 移除指定类型的事件回调
     */
    fun removeEventCallback(eventType: String) {
        callbackMap.remove(eventType)
        Log.d(TAG, "移除事件回调: $eventType")
    }
    
    /**
     * Function: 清理插件资源
     * Note: 清理所有资源和连接
     */
    fun cleanup() {
        try {
            bluetoothManager.cleanup()
            callbackMap.clear()
            isInitialized = false
            
            Log.d(TAG, "插件资源清理完成")
            
        } catch (e: Exception) {
            Log.e(TAG, "清理资源失败", e)
        }
    }
    
    /**
     * Function: 创建内部事件监听器
     * Return: BluetoothEventListener - 事件监听器
     * Note: 创建内部使用的事件监听器，转发事件到UniApp
     */
    private fun createInternalEventListener(): BluetoothEventListener {
        return object : SimpleBluetoothEventListener() {
            
            override fun onDeviceFound(device: BluetoothDevice) {
                val deviceData = mapOf(
                    "deviceId" to device.deviceId,
                    "deviceName" to (device.deviceName ?: ""),
                    "macAddress" to device.macAddress,
                    "signalStrength" to device.signalStrength,
                    "signalDescription" to device.getSignalStrengthDescription()
                )
                
                notifyEvent("onDeviceFound", deviceData)
            }
            
            override fun onScanStarted() {
                notifyEvent("onScanStarted", mapOf(
                    "timestamp" to System.currentTimeMillis(),
                    "message" to "扫描已开始"
                ))
            }
            
            override fun onScanCompleted(devices: List<BluetoothDevice>) {
                val devicesData = devices.map { device ->
                    mapOf(
                        "deviceId" to device.deviceId,
                        "deviceName" to (device.deviceName ?: ""),
                        "macAddress" to device.macAddress,
                        "signalStrength" to device.signalStrength
                    )
                }
                
                notifyEvent("onScanCompleted", mapOf(
                    "devices" to devicesData,
                    "count" to devices.size
                ))
            }
            
            override fun onScanFailed(errorCode: Int, errorMessage: String) {
                notifyEvent("onScanFailed", mapOf(
                    "errorCode" to errorCode,
                    "message" to errorMessage,
                    "timestamp" to System.currentTimeMillis()
                ))
            }
            
            override fun onDeviceConnected(device: BluetoothDevice, connectionInfo: ConnectionInfo) {
                val eventData = mapOf(
                    "device" to mapOf(
                        "deviceId" to device.deviceId,
                        "deviceName" to (device.deviceName ?: ""),
                        "macAddress" to device.macAddress
                    ),
                    "connectionInfo" to mapOf(
                        "connectionId" to connectionInfo.connectionId,
                        "state" to connectionInfo.getStateDescription(),
                        "connectTime" to connectionInfo.connectTime
                    )
                )
                
                notifyEvent("onDeviceConnected", eventData)
            }
            
            override fun onDeviceDisconnected(device: BluetoothDevice, connectionInfo: ConnectionInfo) {
                val eventData = mapOf(
                    "device" to mapOf(
                        "deviceId" to device.deviceId,
                        "deviceName" to (device.deviceName ?: ""),
                        "macAddress" to device.macAddress
                    ),
                    "connectionInfo" to mapOf(
                        "connectionId" to connectionInfo.connectionId,
                        "state" to connectionInfo.getStateDescription(),
                        "disconnectTime" to connectionInfo.disconnectTime
                    )
                )
                
                notifyEvent("onDeviceDisconnected", eventData)
            }
            
            override fun onConnectionStateChanged(connectionInfo: ConnectionInfo) {
                val eventData = mapOf(
                    "deviceId" to connectionInfo.deviceId,
                    "connectionId" to connectionInfo.connectionId,
                    "state" to connectionInfo.state.name,
                    "stateDescription" to connectionInfo.getStateDescription(),
                    "connectTime" to connectionInfo.connectTime,
                    "disconnectTime" to connectionInfo.disconnectTime,
                    "signalStrength" to connectionInfo.signalStrength,
                    "timestamp" to System.currentTimeMillis()
                )
                
                Log.d(TAG, "连接状态变化事件: ${connectionInfo.deviceId} -> ${connectionInfo.state.name}")
                notifyEvent("onConnectionStateChanged", eventData)
            }
            
            override fun onConnectionFailed(device: BluetoothDevice, errorCode: Int, errorMessage: String) {
                val eventData = mapOf(
                    "device" to mapOf(
                        "deviceId" to device.deviceId,
                        "deviceName" to (device.deviceName ?: ""),
                        "macAddress" to device.macAddress
                    ),
                    "errorCode" to errorCode,
                    "errorMessage" to errorMessage,
                    "timestamp" to System.currentTimeMillis()
                )
                
                notifyEvent("onConnectionFailed", eventData)
                Log.e(TAG, "设备连接失败: ${device.getDisplayName()} - $errorMessage (错误码: $errorCode)")
            }
            
            override fun onDataReceived(dataRecord: DataRecord) {
                val eventData = mapOf(
                    "recordId" to dataRecord.recordId,
                    "deviceId" to dataRecord.deviceId,
                    "dataType" to dataRecord.getDataTypeDescription(),
                    "timestamp" to dataRecord.timestamp,
                    "dataPoints" to dataRecord.dataPoints.map { point ->
                        mapOf(
                            "metricName" to point.metricName,
                            "value" to point.value,
                            "unit" to point.unit,
                            "formattedValue" to point.getFormattedValue()
                        )
                    },
                    "rawDataHex" to dataRecord.getRawDataHex()
                )
                
                notifyEvent("onDataReceived", eventData)
            }
            
            override fun onError(errorCode: Int, errorMessage: String, throwable: Throwable?) {
                val eventData = mapOf(
                    "errorCode" to errorCode,
                    "errorMessage" to errorMessage,
                    "timestamp" to System.currentTimeMillis()
                )
                
                notifyEvent("onError", eventData)
            }
            
            override fun onProtocolMessageReceived(protocolMessage: com.example.launibleplugin.protocol.ProtocolMessage, deviceId: String) {
                val eventData = when (protocolMessage) {
                    is com.example.launibleplugin.protocol.AxDateMessage -> {
                        mapOf(
                            "messageType" to "AxDateMessage",
                            "deviceId" to deviceId,
                            "command" to protocolMessage.command,
                            "param1" to protocolMessage.param1,
                            "param2" to protocolMessage.param2,
                            "param3" to protocolMessage.param3,
                            "timeData" to protocolMessage.timeData,
                            "checksum" to protocolMessage.checksum,
                            "timestamp" to System.currentTimeMillis()
                        )
                    }
                    is com.example.launibleplugin.protocol.AxFvcMessage -> {
                        mapOf(
                            "messageType" to "AxFvcMessage",
                            "deviceId" to deviceId,
                            "command" to protocolMessage.command,
                            "testNumber" to protocolMessage.testNumber,
                            "testCount" to protocolMessage.testCount,
                            "pef" to protocolMessage.pef,
                            "fev1" to protocolMessage.fev1,
                            "fev025" to protocolMessage.fev025,
                            "fvc" to protocolMessage.fvc,
                            "mef75" to protocolMessage.mef75,
                            "mef50" to protocolMessage.mef50,
                            "mef25" to protocolMessage.mef25,
                            "mmef" to protocolMessage.mmef,
                            "fev1_fvc" to protocolMessage.fev1_fvc,
                            "fet" to protocolMessage.fet,
                            "temperature" to protocolMessage.temperature,
                            "pressure" to protocolMessage.pressure,
                            "humidity" to protocolMessage.humidity,
                            "reserved1" to protocolMessage.reserved1,
                            "heartRate" to protocolMessage.heartRate,
                            "oxygenSaturation" to protocolMessage.oxygenSaturation,
                            "testQuality" to protocolMessage.testQuality,
                            "checksum" to protocolMessage.checksum,
                            "timestamp" to System.currentTimeMillis()
                        )
                    }
                    else -> {
                        mapOf(
                            "messageType" to "Unknown",
                            "deviceId" to deviceId,
                            "className" to protocolMessage::class.java.simpleName,
                            "timestamp" to System.currentTimeMillis()
                        )
                    }
                }
                
                Log.d(TAG, "协议消息事件: ${eventData["messageType"]} from $deviceId")
                notifyEvent("onProtocolMessageReceived", eventData)
            }
        }
    }
    
    /**
     * Function: 通知事件到UniApp
     * Parameter: eventType - 事件类型
     * Parameter: data - 事件数据
     * Note: 将事件数据转换为JSON并通知到UniApp
     */
    private fun notifyEvent(eventType: String, data: Any) {
        coroutineScope.launch {
            try {
                val callback = callbackMap[eventType]
                if (callback != null) {
                    val eventJson = createResponse(true, eventType, data)
                    callback(eventJson)
                } else {
                    Log.d(TAG, "未设置事件回调: $eventType")
                }
            } catch (e: Exception) {
                Log.e(TAG, "通知事件失败: $eventType", e)
            }
        }
    }
    
    /**
     * Function: 创建统一响应格式
     * Parameter: success - 是否成功
     * Parameter: message - 消息内容
     * Parameter: data - 数据内容（可选）
     * Return: String - JSON格式的响应
     * Note: 创建统一格式的API响应
     */
    private fun createResponse(success: Boolean, message: String, data: Any? = null): String {
        val response = mutableMapOf<String, Any>(
            "success" to success,
            "message" to message,
            "timestamp" to System.currentTimeMillis()
        )
        
        if (data != null) {
            response["data"] = data
        }
        
        return gson.toJson(response)
    }
    
    /**
     * Function: 十六进制字符串转字节数组
     * Parameter: hexString - 十六进制字符串
     * Return: ByteArray - 字节数组
     * Note: 将十六进制字符串转换为字节数组
     */
    private fun hexStringToByteArray(hexString: String): ByteArray {
        val cleanHex = hexString.replace(" ", "").replace("-", "")
        val len = cleanHex.length
        val data = ByteArray(len / 2)
        
        for (i in 0 until len step 2) {
            data[i / 2] = ((Character.digit(cleanHex[i], 16) shl 4) + Character.digit(cleanHex[i + 1], 16)).toByte()
        }
        
        return data
    }
}